﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using Sherwood.SignOn.Server.Models.Repositories;
using Sherwood.Mvc;
using Sherwood.SignOn.Server.Models.Services;
using Sherwood.SignOn.Server.Content;

namespace Sherwood.SignOn.Server.Models.ViewModels
{
    /// <summary>
    /// View model for the UserAccount/ForgotPassword action.
    /// </summary>
    public class ForgotPasswordViewModel : ViewModelBase
    {
        public string RequestedUrl { get; set; }
        public string UserName { get; set; }
        public string Email { get; set; }

        /// <summary>
        /// Initiates a password change process. If the UserName or Email values match an existing user,
        /// an email is sent to the user with a link enabling them to reset their password.
        /// </summary>
        /// <param name="state"></param>
        /// <returns>True if password reset request was successful and email sent to user.
        /// False if password request could not be completed or email not sent.</returns>
        public bool RequestPasswordReset(ModelStateDictionary state)
        {
            Email = Email != null ? Email.Trim().ToLower() : "";
            UserName = UserName != null ? UserName.Trim().ToLower() : "";

            IUserAccount account = null;

            if (Email != "" && UserName != "")
            {
                account = Data.UserAccounts.GetUserAccountByUsernameAndEmail(UserName, Email);
                if (account == null)
                {
                    state.AddModelError("UserName", Translations.ForgotPassword_No_Match_Found + " " + Translations.ForgotPassword_Enter_Email_Or_Username);
                    return false;
                }
            }
            else
            {
                if (Email != "")
                {
                    account = Data.UserAccounts.GetUserAccountByEmail(Email);
                    if (account == null)
                    {
                        state.AddModelError("",Translations.ForgotPassword_No_Match_Found);
                        state.AddModelError("Email",Translations.ForgotPassword_Email_Not_Found);
                        return false;
                    }
                }
                if (UserName != "")
                {
                    account = Data.UserAccounts.GetUserAccountByUsername(UserName);
                    if (account == null)
                    {
                        state.AddModelError("", Translations.ForgotPassword_No_Match_Found);
                        state.AddModelError("UserName", Translations.ForgotPassword_Username_Not_Found);
                        return false;
                    }
                }
            }

            if (account != null)
            {
                if (!account.IsEnabled)
                {
                    state.AddModelError("", Translations.ForgotPassword_Account_Disabled);
                    return false;
                }
                else
                {

                    VerificationStatus originalVerificationStatus = account.VerificationStatus;
                    string originalVerificationCode = account.VerificationCode;
                    string originalRequestedUrl = account.RequestedUrl;

                    account.CreateVerificationCode();
                    account.SetVerificationParameters(VerificationStatus.ResetPassword, RequestedUrl, account.VerificationCode);


                    //Send email
                    string subject = Translations.ForgotPassword_Email_Subject.Parameterize(account, this, Config.Settings);
                    string body = Translations.ForgotPassword_Email_Template.Parameterize(account, this, Config.Settings);
                    bool emailSent = false;
                    string emailError = "";
                    try
                    {
                        emailSent = EmailHelper.SendEmailToUser(subject, body, account, account.Email);
                    }
                    catch (Exception ex)
                    {
                        emailSent = false;
                        emailError = ex.Message;
                    }
                    if (!emailSent)
                    {
                        state.AddModelError("", Translations.ForgotPassword_Unable_To_Send_Email + "<br />" + emailError);
                    }
                    return emailSent;
 
                }

            }
            else
            {
                state.AddModelError("", Translations.ForgotPassword_No_Match_Found);
            }


            return false;
        }
    }
}
